/* Laboratorio # 2 - Administración de bases de datos
 Jorge Fallas Ramos         402090469
 José Roberto Sánchez       115400070
 Daniel Villalobos Venegas  402110100
 */
package monitorinitdb.Vista;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;

public class VentTableSpace extends JFrame implements ActionListener {

    public static VentTableSpace instance;

    public static VentTableSpace getInstance() {
        if (instance == null) {
            instance = new VentTableSpace();
        }
        return instance;
    }

    public static String getTableSpace() throws Exception {
        if (instance != null) {
            return instance.obtTS();
        }
        return null;

    }

    private JButton btSelArchivo(String name) {
        JButton b = new JButton("<html>Seleccionar<br>Archivo</html>");
        b.setActionCommand("Seleccionar Archivo");
        b.addActionListener(this);
        b.setName(name);
        return b;
    }

    public static void clean() {
        if (instance != null) {
            instance.limpiar();
        }
    }

    String[] acciones = {"Agregar Tablespace", "Limpiar", "Continuar"};

    ArrayList<JTextField> tS, datafile, tam, tamAut, maxsize;
    ArrayList<JCheckBox> opautoExt, undo;
    ArrayList<JCheckBox> reuse;

    int cantTS;
    JPanel listTS;

    private VentTableSpace() throws HeadlessException {
        tS = new ArrayList<>();
        tam = new ArrayList<>();
        tamAut = new ArrayList<>();
        maxsize = new ArrayList<>();
        opautoExt = new ArrayList<>();
        datafile = new ArrayList<>();
        undo = new ArrayList<>();
        reuse = new ArrayList<>();
        cantTS = 0;
        configSelArchiv();
        configInicial();
        configComp();
    }

    private void configComp() {
        JPanel end = new JPanel(new BorderLayout());

        listTS = new JPanel();
        listTS.setLayout(new BoxLayout(listTS, BoxLayout.Y_AXIS));
        JScrollPane scroll = new JScrollPane(listTS, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scroll.setAutoscrolls(true);
        scroll.setMaximumSize(new Dimension(350, 350));
        scroll.setPreferredSize(scroll.getMaximumSize());
        end.add(scroll, BorderLayout.CENTER);
        add(end, BorderLayout.CENTER);
        JLabel l = new JLabel("<html>Seleccione el boton agregar tablespaces para agregar un tablespace<br>Presione el boton continuar para continuar con la instalación</html>");
        l.setHorizontalAlignment(JLabel.CENTER);
        add(l, BorderLayout.NORTH);

        JPanel btn = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        JButton b;
        for (String s : acciones) {
            b = new JButton(s);
            b.setActionCommand(s);
            btn.add(b);
            b.addActionListener(this);
        }
        add(btn, BorderLayout.SOUTH);

    }

    private JPanel genTS() {
        String name = "TableSpace_" + cantTS;
        cantTS++;
        JPanel l = new JPanel(new FlowLayout());

        l.add(new JLabel("Tablespace:"));
        JTextField tex = new JTextField();
        tex.setName(name);
        tex.setPreferredSize(new Dimension(100, 35));
        tS.add(tex);
        l.add(tex);
        JButton sel = btSelArchivo(name);
        l.add(sel);

        l.add(new JLabel("DataFile:"));
        tex = new JTextField();
        tex.setName(name);
        tex.setPreferredSize(new Dimension(100, 35));
        l.add(tex);
        tex.setEditable(false);
        datafile.add(tex);

        l.add(new JLabel("Tamaño:"));
        tex = new JTextField();
        tex.setName(name);
        tex.setPreferredSize(new Dimension(65, 35));
        l.add(tex);
        tam.add(tex);

        JCheckBox ck = new JCheckBox("AutoExtend");
        l.add(ck);
        opautoExt.add(ck);
        ck.addActionListener(this);
        ck.setActionCommand("Extend");
        ck.setName(name);

        tex = new JTextField();
        tex.setName(name);
        tex.setPreferredSize(new Dimension(65, 35));
        l.add(new JLabel("on next:"));
        l.add(tex);
        tex.setEnabled(false);
        tamAut.add(tex);

        tex = new JTextField();
        tex.setName(name);
        tex.setPreferredSize(new Dimension(65, 35));
        tex.setEnabled(false);
        maxsize.add(tex);

        l.add(new JLabel("maxsize:"));
        l.add(tex);

        JCheckBox undoChk = new JCheckBox("Undo");
        undoChk.setActionCommand("Undo");
        l.add(undoChk);
        undo.add(ck);
        undoChk.setName(name);
        undoChk.addActionListener(this);

        JCheckBox reuseChk = new JCheckBox("Reuse");
        l.add(reuseChk);
        reuse.add(reuseChk);
        reuseChk.setEnabled(false);
        reuseChk.setName(name);

        JButton bt = new JButton("Eliminar");
        bt.setActionCommand("Eliminar");
        bt.setName(name);
        bt.addActionListener(this);
        l.add(bt);
        l.setBorder(BorderFactory.createRaisedSoftBevelBorder());
        l.setName(name);
        return l;
    }

    private void configInicial() {
        setTitle("Configura Tablespace");
        setPreferredSize(new Dimension(1040, 400));
        setMinimumSize(this.getPreferredSize());
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                setVisible(false);
                VentConfig.getInstance().mostrar();
            }

        });
    }

    JFileChooser selArchivo;

    private void configSelArchiv() {
        selArchivo = new JFileChooser();
        selArchivo.setDialogType(JFileChooser.SAVE_DIALOG);
        selArchivo.addChoosableFileFilter(new FileNameExtensionFilter("Datafile", "dbf"));
        selArchivo.addChoosableFileFilter(new FileNameExtensionFilter("ControlFile", "ctr"));
    }

    private void cambiaDataFile(String name) throws Exception {
        int status = selArchivo.showSaveDialog(null);
        JTextField elegido = null;
        if (status == JFileChooser.APPROVE_OPTION) {
            File f = selArchivo.getSelectedFile();
            if (!f.getAbsolutePath().endsWith(".dbf")) {
                f = new File(f.getAbsolutePath() + ".dbf");
            }
            if (f.exists()) {
                throw new Exception("Datafile ya creado");
            }

            for (JTextField tex : datafile) {
                if (tex.getText().equals(f.getAbsolutePath())) {
                    throw new Exception("Datafile ya elegido para otro tablespace");
                }
                if (tex.getName().equals(name)) {
                    elegido = tex;
                }
            }

            String[] vec = VentConfig.getTSData();
            if (vec != null) {
                for (String s : vec) {
                    if (s.equals(f.getAbsolutePath())) {
                        throw new Exception("Datafile ya elegido para otro tablespace");
                    }
                }
            }

            if (elegido != null) {
                elegido.setText(f.getAbsolutePath());
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (e.getActionCommand()) {
            case "Undo": {
                JCheckBox u = (JCheckBox) e.getSource();
                for (JCheckBox k : reuse) {
                    if (k.getName().equals(k.getName())) {
                        k.setEnabled(u.isSelected());
                    }
                }
            }
            break;
            case "Agregar Tablespace": {
                listTS.add(genTS());
                getContentPane().revalidate();
            }
            break;
            case "Seleccionar Archivo": {
                System.out.println("Seleccionar archivo");
                JButton bt = (JButton) e.getSource();
                try {
                    cambiaDataFile(bt.getName());
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
                }
            }
            break;
            case "Extend": {
                JCheckBox ck = (JCheckBox) e.getSource();
                String s = ck.getName();
                boolean b = ck.isSelected();
                for (int i = 0; i < maxsize.size(); i++) {
                    if (maxsize.get(i).getName().equals(s)) {
                        maxsize.get(i).setEnabled(b);
                        tamAut.get(i).setEnabled(b);
                        break;
                    }
                }
                listTS.repaint();
                getContentPane().revalidate();
            }
            break;
            case "Eliminar": {
                JButton bt = (JButton) e.getSource();
                elimTS(bt.getName());
                listTS.repaint();
                getContentPane().revalidate();
            }
            break;
            case "Limpiar": {
                limpiar();
                getContentPane().revalidate();
            }
            break;
            case "Continuar": {
                setVisible(false);
                VentConfig.getInstance().mostrar();
            }
            break;
            default:
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    }

    private void elimTS(String name) {
        for (int i = 0; i < listTS.getComponentCount(); i++) {
            if (listTS.getComponents()[i].getName().equals(name)) {
                listTS.remove(i);
                tam.remove(i);
                tamAut.remove(i);
                opautoExt.remove(i);
                tS.remove(i);
                datafile.remove(i);
                maxsize.remove(i);
            }
        }
    }

    public void mostrar() {
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        VentTableSpace.getInstance().mostrar();
    }

    void limpiar() {
        listTS.removeAll();
        listTS.repaint();
        cantTS = 0;
        maxsize.clear();
        tam.clear();
        tamAut.clear();
        opautoExt.clear();
        tS.clear();
        datafile.clear();
    }

    private boolean valido(int pos) {
        if (opautoExt.get(pos).isSelected()) {

            if (tamAut.get(pos).getText().equals("") || maxsize.get(pos).getText().equals("") || tamAut.get(pos).getText().contains(" ") || maxsize.get(pos).getText().contains(" ")) {
                return false;
            }
        }
        if (tS.get(pos).getText().equals("") || datafile.get(pos).getText().equals("") || tam.get(pos).getText().equals("") || tam.get(pos).getText().contains(" ") || tS.get(pos).getText().contains(" ")) {
            return false;
        }
        return true;
    }

    public String obtTS() throws Exception {
        StringBuilder hilera = new StringBuilder();
        for (int i = 0; i < tS.size(); i++) {
            if (valido(i)) {
                if (undo.get(i).isSelected()) {
                    hilera.append("CREATE UNDO TABLESPACE ");
                } else {
                    hilera.append("CREATE TABLESPACE ");
                }
                hilera.append(tS.get(i).getText()).append(" DATAFILE '").append(datafile.get(i).getText()).append("' SIZE ").append(tam.get(i).getText());
                if (undo.get(i).isSelected() && reuse.get(i).isSelected()) {
                    hilera.append(" REUSE");
                }
                if (opautoExt.get(i).isSelected()) {
                    hilera.append(" AUTOEXTEND ON NEXT ").append(tamAut.get(i).getText()).append(" MAXSIZE ").append(maxsize.get(i).getText());
                }
                hilera.append(";\n");
            } else {
                throw new Exception("Campo vacio, revise los tablespace");
            }
        }
        return hilera.toString();
    }
}
